#include "pcf8574.h"


u8 PCF8574_Timer;

void I2C_Start(void)
{ 
  taskENTER_CRITICAL();           //进入临界区    
  PCF8574_SDA_OUT;         
  PCF8574_SDA=1;    
  PCF8574_SCL=1;   
  delay_us(5);    
  PCF8574_SDA=0;  
  delay_us(5);   
  PCF8574_SCL=0;
    taskEXIT_CRITICAL();            //退出临界区
}

void I2C_Stop(void)
{  
    taskENTER_CRITICAL();           //进入临界区
  PCF8574_SDA_OUT;     
  PCF8574_SDA=0;    
  PCF8574_SCL=0;   
  delay_us(5);  
  PCF8574_SCL=1;    
  delay_us(5);  
  PCF8574_SDA=1;   
  delay_us(5);
    taskEXIT_CRITICAL();            //退出临界区
}

u8 I2C_Write_Byte(u8 data)
{    
   u8 k;
   taskENTER_CRITICAL();           //进入临界区    
   for(k=0;k<8;k++)
   {
            //发送8bit数据        
     delay_us(5);        
     if(data&0x80)
     {            
       PCF8574_SDA=1;        
     }
     else
     {            
       PCF8574_SDA=0;        
     }        
     data=data<<1;        
     delay_us(5);        
     PCF8574_SCL=1;                
     delay_us(5);        
     PCF8574_SCL=0;    
  }    
  delay_us(5);//延时读取ACK响应    
  PCF8574_SDA=1;      
  PCF8574_SDA_IN ;//设为输入    
  delay_us(5);    
  PCF8574_SCL=1;       
  delay_us(5);      
  k=PCF8574_SDA_DataIN;//读取ACK/NACK    
  delay_us(5);    
  PCF8574_SCL=0;    
  delay_us(5);    
  PCF8574_SDA_OUT;
    taskEXIT_CRITICAL();            //退出临界区
  if(k)
  {         
     return 0;    //NACK响应
  }    
  return 1;
}

u8 I2C_Read_Byte(u8 flag)
{    
  u32 k,data; 
  taskENTER_CRITICAL();           //进入临界区    
  PCF8574_SDA_IN ; //置为输入线    
  data=0;    
  for(k=0;k<8;k++) //接收8bit数据
  {            
    delay_us(5);        
    PCF8574_SCL=1;        
    delay_us(5);              
    data=data|PCF8574_SDA_DataIN;//读数据        
    data=data<<1;        
    delay_us(5);        
    PCF8574_SCL=0;        
    delay_us(5);     
  }    
  data=data>>1;    //往回移动1次    
  PCF8574_SDA_OUT;    //置为输出线    
  if(flag)
  {        
    PCF8574_SDA=1;    //拉高为NACK    
  }
  else
  {        
    PCF8574_SDA=0;    //拉低为ACK    
  }    
  delay_us(5);    
  PCF8574_SCL=1;        
  delay_us(5);    
  PCF8574_SCL=0;    
  delay_us(5);    
  PCF8574_SDA_OUT;
  taskEXIT_CRITICAL();            //退出临界区     
  return (u8)data;    //返回读取的数据
}

u8 PCF8574_Read(u8 PCF8574TS)
{    
  u8 state;    
  u8 data=0;
    taskENTER_CRITICAL();           //进入临界区
  I2C_Start();                                    //启动I2C总线    
  state = I2C_Write_Byte(PCF8574TS);        //发送器件地址,主机读    
  if(state == 1)
  {        
     data = I2C_Read_Byte(0x01);    //读取数据            
  }
  else
  {        
     data =-1;    
  }    
  I2C_Stop();    
    taskEXIT_CRITICAL();             //退出临界区    
  return data;
}

u8 PCF8574_Write(u8 PCF8574TS,u8 data)
{    
  u8 state,ret;    
  I2C_Start();                                    //启动I2C总线    
  state = I2C_Write_Byte(PCF8574TS);    //发送器件地址,主机写    
  if(state==1)
  {          
    state = I2C_Write_Byte(data);        
    if(state==1)
    {            
      ret = 1;         
    }
    else
    {            
      ret = 0;        
    }    
  }
  else
  {        
    ret = 0;    
  }    
  I2C_Stop();    
  return ret;
}

u8 PCF8574ATemp;
u8 PCF8574BTemp;
u8 Pin[9]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
void ControlPin(u8 add,u8 pin,u8 onoff)
{
  if(add==PCF8574A_write)
  { 
    PCF8574ATemp=ReadPCF8574A;
    if(onoff)PCF8574ATemp|=Pin[pin]; 
    else PCF8574ATemp&=~Pin[pin];
    PCF8574_Write(add,PCF8574ATemp);
  }  
  if(add==PCF8574B_write)
  {
    PCF8574BTemp=ReadPCF8574B; 
    if(onoff)PCF8574BTemp|=Pin[pin];
    else PCF8574BTemp&=~Pin[pin];
    PCF8574_Write(add,PCF8574BTemp);
  }    
}

//PCF8574初始化函数
void Init_PCF8574(void)
{ 
  
}



